/******************************************************************************* * GenPlay, Einstein Genome Analyzer * Copyright (C) 2009, 2014 Albert Einstein College of Medicine * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * Authors: Julien Lajugie <julien.lajugie@einstein.yu.edu> * Nicolas Fourel <nicolas.fourel@einstein.yu.edu> * Eric Bouhassira <eric.bouhassira@einstein.yu.edu> * * Website: <http://genplay.einstein.yu.edu> ******************************************************************************/ package edu.yu.einstein.genplay.gui.dialog.multiGenomeDialog.vcfLoader; import java.awt.FontMetrics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.swing.DefaultCellEditor; import javax.swing.JComboBox; import javax.swing.JTable; import javax.swing.table.TableCellEditor; import javax.swing.table.TableColumn; import edu.yu.einstein.genplay.core.multiGenome.VCF.VCFFile.VCFFile; import edu.yu.einstein.genplay.exception.ExceptionManager; import edu.yu.einstein.genplay.gui.MGDisplaySettings.MGDisplaySettings; import edu.yu.einstein.genplay.gui.customComponent.customComboBox.CustomComboBox; import edu.yu.einstein.genplay.gui.customComponent.customComboBox.CustomFileComboBoxMG; import edu.yu.einstein.genplay.gui.customComponent.customComboBox.CustomStringComboBox; import edu.yu.einstein.genplay.gui.customComponent.customComboBox.customComboBoxEvent.CustomComboBoxEvent; import edu.yu.einstein.genplay.gui.customComponent.customComboBox.customComboBoxEvent.CustomComboBoxListener; import edu.yu.einstein.genplay.gui.fileFilter.ExtendedFileFilter; import edu.yu.einstein.genplay.gui.fileFilter.VCFFilter; /** * This class is the table for {@link VCFLoaderDialog} * * @author Nicolas Fourel * @version 0.1 */ public class VCFLoaderTable extends JTable implements CustomComboBoxListener, ActionListener { /** * Generated serial version ID */ private static final long serialVersionUID = 9060290582452147288L; private CustomStringComboBox groupBox; // the box for Group column private CustomStringComboBox genomeBox; // the box for Genome column private CustomFileComboBoxMG fileBox; // the box for VCF file column private final List<JComboBox> rawComboList; private int lastRow = 0; // saves the row index of the last event on getCellEditor private int lastCol = 0; // saves the column index of the last event on getCellEditor private final Map<String, List<String>> temporaryFileAndGenomeNameMap; private final List<VCFFile> vcfFileList; /** * Constructor of {@link VCFLoaderTable} * @param model */ public VCFLoaderTable (VCFLoaderModel model) { super(model); temporaryFileAndGenomeNameMap = new HashMap<String, List<String>>(); vcfFileList = new ArrayList<VCFFile>(); rawComboList = new ArrayList<JComboBox>(); initializesBoxes(); } @Override public void actionPerformed(ActionEvent e) { if (e.getSource() instanceof RawNameComboBox) { RawNameComboBox box = (RawNameComboBox) e.getSource(); if (box.isClicked()) { updateRawName(lastRow); } } } /** * Adds an empty row */ public void addEmptyRow() { VCFLoaderModel model = (VCFLoaderModel) getModel(); model.addEmptyRow(); String defaultGroupValue = MGDisplaySettings.getInstance().getVariousSettings().getDefaultGroupText(); if (model.getData().size() == 1) { groupBox.addElement(defaultGroupValue); groupBox.resetCombo(); } model.setValueAt(defaultGroupValue, model.getData().size() - 1, VCFData.GROUP_INDEX); } @Override public void customComboBoxChanged(CustomComboBoxEvent evt) { Object value = evt.getElement(); setValueAt(value, lastRow, lastCol); updateSize(value, lastCol); if ((lastCol == VCFData.FILE_INDEX) && !value.toString().equals(CustomComboBox.ADD_TEXT)) { String filePath = value.toString(); List<String> rawGenomeNames = null; if (temporaryFileAndGenomeNameMap.containsKey(filePath)) { rawGenomeNames = temporaryFileAndGenomeNameMap.get(filePath); } else { File file = new File(value.toString()); VCFFile vcfFile = getVCFFile(file); rawGenomeNames = vcfFile.getHeader().getGenomeRawNames(); temporaryFileAndGenomeNameMap.put(filePath, rawGenomeNames); } if (rawGenomeNames != null) { setValueAt(rawGenomeNames.get(0), lastRow, VCFData.RAW_INDEX); updateRawName(lastRow); } } } @Override public TableCellEditor getCellEditor(int row, int column) { lastRow = row; lastCol = column; switch (column) { case VCFData.RAW_INDEX: try { JComboBox combo; if (lastRow < rawComboList.size()) { combo = rawComboList.get(lastRow); } else { File file = (File) getValueAt(row, VCFData.FILE_INDEX); VCFFile vcfFile = getVCFFile(file); List<String> rawGenomeNames = vcfFile.getHeader().getGenomeRawNames(); combo = new RawNameComboBox(rawGenomeNames.toArray()); combo.addActionListener(this); rawComboList.add(combo); } return new DefaultCellEditor(combo); } catch (Exception e) { System.out.println("not a valid file: " + getValueAt(row, VCFData.FILE_INDEX)); return super.getCellEditor(row, column); } default: return super.getCellEditor(row, column); } } /** * @return the data */ public List<VCFData> getData() { return ((VCFLoaderModel)getModel()).getData(); } @Override public Object getValueAt(int row, int col) { Object value = getModel().getValueAt(row, col); switch (col) { case VCFData.GROUP_INDEX: if (value.toString().equals("")) { value = CustomComboBox.ADD_TEXT; } break; case VCFData.NICKNAME_INDEX: if (value.toString().equals("")) { value = CustomComboBox.ADD_TEXT; } break; case VCFData.RAW_INDEX: if (value.toString().equals("")) { value = "..."; } break; case VCFData.FILE_INDEX: if (value == null) { value = CustomComboBox.ADD_TEXT; } break; default: value = new Object(); } return value; } /** * @param file * @return the existing VCF file (if exists) or a new VCF File */ public VCFFile getVCFFile (File file) { for (VCFFile vcfFile: vcfFileList) { if (vcfFile.getFile().getAbsoluteFile().equals(file.getAbsoluteFile())) { return vcfFile; } } VCFFile vcfFile = null; try { vcfFile = new VCFFile(file); } catch (Exception e) { ExceptionManager.getInstance().caughtException(e); } vcfFileList.add(vcfFile); return vcfFile; } /** * initializes the different combo boxes used in the table */ private void initializesBoxes () { TableColumn column; // Group combo box groupBox = new CustomStringComboBox(); groupBox.getRenderer().addCustomComboBoxListener(this); column = getColumnModel().getColumn(VCFData.GROUP_INDEX); column.setCellEditor(new DefaultCellEditor(groupBox)); // Genome combo box genomeBox = new CustomStringComboBox(); genomeBox.getRenderer().addCustomComboBoxListener(this); column = getColumnModel().getColumn(VCFData.NICKNAME_INDEX); column.setCellEditor(new DefaultCellEditor(genomeBox)); // File combo box fileBox = new CustomFileComboBoxMG(this); fileBox.getRenderer().addCustomComboBoxListener(this); ExtendedFileFilter[] filter = {new VCFFilter()}; fileBox.setFilters(filter); column = getColumnModel().getColumn(VCFData.FILE_INDEX); column.setCellEditor(new DefaultCellEditor(fileBox)); } /** * @param data the data to set */ public void setData(List<VCFData> data) { List<VCFData> newData = new ArrayList<VCFData>(); for (int i = 0; i < data.size(); i++) { VCFData rowData = new VCFData(); rowData.setGroup(data.get(i).getGroup()); rowData.setNickname(data.get(i).getNickname()); rowData.setRaw(data.get(i).getRaw()); rowData.setFile(data.get(i).getFile()); newData.add(rowData); } ((VCFLoaderModel)getModel()).setData(newData); initializesBoxes(); for (VCFData vcfData: data) { groupBox.addElement(vcfData.getGroup()); genomeBox.addElement(vcfData.getNickname()); fileBox.addElement(vcfData.getFile()); } if (data.size() > 0) { groupBox.resetCombo(); genomeBox.resetCombo(); fileBox.resetCombo(); } } /** * Updates the nickname box in a row according to the selected raw name of the same row * @param row a row */ private void updateRawName (int row) { String rawName = (String) getValueAt(row, VCFData.RAW_INDEX);; if ((rawName != null) && !rawName.isEmpty()) { genomeBox.addElement(rawName); genomeBox.resetCombo(); ((VCFLoaderModel) getModel()).setValueAt(rawName, row, VCFData.NICKNAME_INDEX); } } /** * Sets the width of a column according to the new value * @param value new value * @param column column index */ private void updateSize (Object value, int column) { FontMetrics fm = getFontMetrics(getFont()); int width = fm.stringWidth(value.toString()); int colWidth = getColumnModel().getColumn(column).getWidth(); if (colWidth < width) { getColumnModel().getColumn(column).setPreferredWidth(width); } } }